import os
import re
from datetime import datetime, timedelta
import tkinter as tk
from tkinter import filedialog
import pandas as pd
from collections import defaultdict

def select_input_directory():
    """选择输入日志目录"""
    root = tk.Tk()
    root.withdraw()
    return filedialog.askdirectory(
        title="选择日志文件目录"
    )

def select_output_file_path():
    """选择输出Excel文件路径"""
    root = tk.Tk()
    root.withdraw()
    return filedialog.asksaveasfilename(
        defaultextension=".xlsx",
        filetypes=[("Excel files", "*.xlsx"), ("All files", "*.*")]
    )

def generate_time_intervals(start, end, interval):
    """生成时间区间列表"""
    intervals = []
    current = start
    while current < end:
        next_time = current + timedelta(minutes=interval)
        intervals.append((current, min(next_time, end)))
        current = next_time
    return intervals

def process_logs(file_path, time_intervals, stats):
    """处理单个日志文件并更新统计结果"""
    # 预编译正则表达式
    timestamp_pat = re.compile(r'\[(\d{2}:\d{2}:\d{2}\.\d{3})\]')
    correct_pat = re.compile(r'^\[\d{2}:\d{2}:\d{2}\.\d{3}\].*?=\d+\.\d{2}.*$')
    est_pat = re.compile(r'est\[[^\]]+\]')
    node_pat = re.compile(r'(?P<hex>[0-9A-Fa-f]{4})\[(?P<coords>(-?\d+\.\d{2},){2}-?\d+\.\d{2})\]=(?P<result>\d+\.\d{2})')

    try:
        with open(file_path, 'r', encoding='GB2312', errors='replace') as file:
            current_block = ""
            for line in file:
                line = line.replace('收←◆', '').strip()
                
                if not line:  # 遇到空行处理块
                    if current_block:
                        process_single_block(
                            current_block, stats, time_intervals,
                            timestamp_pat, correct_pat, est_pat, node_pat
                        )
                    current_block = ""
                else:
                    current_block += line

            # 处理最后一个块
            if current_block:
                process_single_block(
                    current_block, stats, time_intervals,
                    timestamp_pat, correct_pat, est_pat, node_pat
                )

    except Exception as e:
        print(f"文件处理错误[{os.path.basename(file_path)}]: {e}")
        
def process_single_block(block, stats, intervals, 
                        ts_pat, valid_pat, est_pat, node_pat):
    """处理单个日志块并更新统计信息"""
    # 提取第一个时间戳
    ts_match = ts_pat.search(block)
    if not ts_match:
        return

    # 构造完整时间对象
    try:
        log_time = datetime.strptime(ts_match.group(1), "%H:%M:%S.%f").replace(
            year=intervals[0][0].year,
            month=intervals[0][0].month,
            day=intervals[0][0].day
        )
    except ValueError:
        return

    # 验证块格式有效性
    cleaned_block = ts_pat.sub('', block)
    
    cleaned_block = f"[{ts_match.group(1)}]{cleaned_block.replace(' ', '')}"
    
    
    if not valid_pat.match(cleaned_block):
        return

    # 确定所属时间区间
    for start, end in intervals:
        if start <= log_time < end:
            time_label = f"{start.strftime('%Y-%m-%d %H:%M:%S')} - {end.strftime('%H:%M:%S')}"
            
            
            if est_pat.search(cleaned_block):
                stats[time_label]['est'] += 1
            else:
                
                conn_count = len(node_pat.findall(cleaned_block))
                print(conn_count)
                stats[time_label][str(conn_count)] += 1  # 将 conn_count 转换为字符串
            break
    
def convert_stats_to_dataframe(stats):
    """将统计字典转换为DataFrame"""
    data = []
    for time_range, counts in stats.items():
        row = {"时间区间": time_range}
        for category, count in counts.items():
            row[str(category)] = count  # 确保键是字符串类型
        data.append(row)
    
    if not data:
        return pd.DataFrame(columns=["时间区间", "est"])
    
    df = pd.DataFrame(data)
    
    # 自动排序列（时间区间 + est + 数字列排序）
    columns_order = ["时间区间"]
    if 'est' in df.columns:
        columns_order.append('est')
    
    # 提取数字列并排序
    numeric_cols = sorted(
        [col for col in df.columns if col != "时间区间" and col != "est" and str(col).isdigit()],
        key=lambda x: int(x)
    )
    
    return df[columns_order + numeric_cols].fillna(0)

def main():
    # 配置时间参数（根据实际日志日期调整）
    start_time = datetime(2025, 2, 27, 0, 0, 0)
    end_time = datetime(2025, 2, 27, 23, 59, 0)
    interval = 60  # 分钟

    # 选择日志目录
    input_dir = select_input_directory()
    if not input_dir:
        print("未选择输入目录")
        return

    # 获取所有txt文件
    log_files = [
        os.path.join(input_dir, f) 
        for f in os.listdir(input_dir) 
        if f.lower().endswith('.txt')
    ]
    if not log_files:
        print("目录中没有找到日志文件")
        return

    # 选择输出文件
    output_path = select_output_file_path()
    if not output_path:
        print("未选择输出文件")
        return

    # 生成时间区间
    time_ranges = generate_time_intervals(start_time, end_time, interval)

    # 初始化统计字典
    stats = defaultdict(lambda: defaultdict(int))

    # 处理所有日志文件
    for file_path in log_files:
        print(f"正在处理: {os.path.basename(file_path)}")
        process_logs(file_path, time_ranges, stats)

    # 生成结果
    result_df = convert_stats_to_dataframe(stats)
    if not result_df.empty:
        result_df.to_excel(output_path, index=False)
        print(f"已处理 {len(log_files)} 个文件，结果保存至: {output_path}")
    else:
        print("未找到有效日志数据")

if __name__ == "__main__":
    main()